// 弹窗复选
import React from 'react';
import { Button, Checkbox, Input, Modal, Space, Switch, Tooltip, Tree } from 'antd';
import { SearchOutlined } from '#/utils/antdIcons';
import TRNotification from '#/utils/notification';
import _ from 'lodash';
import { TRDefault } from '@/components';
import styles from './index.less';

class ModalComponent extends React.Component {
  constructor(props) {
    super(props);
    const { treeData = [], multiple = true } = props;

    this.state = {
      first: true,
      visible: true,
      checkAll: false,
      indeterminate: false,
      autoExpandParent: true,
      checkedKeys: [],
      checkedNodes: [],
      expandedKeys: [],
      searchValue: '',
      searchChecked: true,
    };
    this.multiple = multiple;
    this.deepLv = 1; // 最深叶子等级
    this.treeDataMap = this._tree2map(treeData, [], null, 1); //最深子项集合
    this.allData = treeData;
    this.treeData = treeData;

    this._onSearch = this._onSearch.bind(this); // 搜索
    this._onChangeAll = this._onChangeAll.bind(this); // 全选
    this._onCheckTree = this._onCheckTree.bind(this); // 树选择
    this._onExpandTree = this._onExpandTree.bind(this); // 树展开
    this._onCancel = this._onCancel.bind(this); // 取消
    this._onOk = this._onOk.bind(this); // 提交
  }

  componentDidMount() {
    this._onCheckTree({ checked: this.multiple ? this.props.value : [this.props.value] });
  }

  _tree2map = (tree = [], list = [], parentKey = null, lv = 1) => {
    // 降维,key要唯一
    if (lv > this.deepLv) this.deepLv = lv;
    for (let i = 0; i < tree.length; i++) {
      const node = tree[i];
      const { key, title } = node;
      node.lv = lv;
      node.parentKey = parentKey;
      list.push({
        key,
        title,
        parentKey,
        lv,
      });
      if (node.children) {
        this._tree2map(node.children, list, node.key, lv + 1);
      }
    }
    return list;
  };

  _isChinese = (s) => {
    // 中文全匹配
    var ret = true;
    for (var i = 0; i < s.length; i++) ret = ret && s.charCodeAt(i) >= 10000;
    return ret;
  };

  _onSearch = (value) => {
    if (!this.allData.length) return;
    let expandedKeys = [];
    let { checkedKeys, checkedNodes, searchChecked } = this.state;
    if (value && this._isChinese(value)) {
      expandedKeys = this.treeDataMap
        .map((x) => (x.title.indexOf(value) > -1 ? x.parentKey : null))
        .filter((item, i, self) => item && self.indexOf(item) === i);
    }
    if (searchChecked || !value) {
      this.treeData = this.allData.filter((t) => {
        if (t.title.includes(value)) return true;
      });
    } else {
      this.treeData = this.allData.filter((t) => {
        if (!t.title.includes(value)) return true;
      });
    }
    // if (expandedKeys?.[0]) {
    //     this.refTree.scrollTo({ key: expandedKeys?.[0], align: 'top' });
    // } else {
    //     this.refTree.scrollTo({ key: 0, align: 'top' });
    // }

    // const checkAll = !!checkedKeys.length && ch eckedNodes.length >= this.treeData.length && this.treeData.every(t => checkedKeys.includes(t.key))
    // const indeterminate = !!checkedKeys.length && !checkAll && this.treeData.length > checkedNodes.length
    this.setState({
      expandedKeys,
      searchValue: value,
      autoExpandParent: true,
      indeterminate: false,
      checkAll: false,
      checkedKeys: [],
      checkedNodes: [],
    });
  };

  _onChangeAll = (e) => {
    const checkAll = e.target.checked,
      checkedNodes = checkAll
        ? [
            // ...(this.state.checkedNodes || []).filter(
            //   (t) => !this.treeData.map((_t) => _t.key).includes(t.key),
            // ),
            ...this._tree2map(this.treeData, [], null, 1),
          ]
        : [],
      checkedKeys = checkedNodes.map((x) => x.key);
    // if (checkAll) {
    //   this.treeData.forEach((x) => {
    //     checkedNodes.push(x);
    //     x.children?.forEach((y) => {
    //       checkedNodes.push(y);
    //       y.children?.forEach((z) => {
    //         checkedNodes.push(z);
    //       });
    //     });
    //   });
    //   checkedNodes.forEach((x) => checkedKeys.push(x.key));
    // }
    this.setState({
      checkAll,
      checkedKeys,
      checkedNodes,
      indeterminate: false,
    });
  };

  _onCheckTree = (val) => {
    // const checkedNodes = this.leafNodes.filter(x => val.checked?.includes(x.key)),//废弃
    // let checkedNodes = [];
    // if (this.multiple) {
    // val.checked?.map(v => {
    //     this.treeData.map(x => {
    //         v === x.key ? checkedNodes.push(x) :
    //             x.children?.map((y) => {
    //                 v === y.key ? checkedNodes.push(y) :
    //                     y.children?.map((z) => {
    //                         v === z.key && checkedNodes.push(z)
    //                     })
    //             })
    //     })
    // })
    // }
    // else {
    //     if (val.checked && val.checked.length > 1) {
    //         val.checked.splice(0, 1)
    //     }
    //     this.treeData.some(x => (
    //         val.checked && val.checked[0] === x.key ? checkedNodes.push(x) :
    //             x.children?.some((y) => (
    //                 val.checked && val.checked[0] === y.key ? checkedNodes.push(y) :
    //                     y.children?.some((z) => (
    //                         val.checked && val.checked[0] === z.key && checkedNodes.push(z)
    //                     ))
    //             ))
    //     ))
    // }
    if (this.state.first) {
      let expandedKeys = this.treeDataMap
        .map((x) => (val.checked.includes(x.key) ? x.parentKey : null))
        .filter((item, i, self) => item && self.indexOf(item) === i);
      this.setState({
        expandedKeys,
        first: false,
      });
    }
    const checkedNodes = [
      // ...(this.state.checkedNodes || []).filter(
      //   (t) => !this.treeData.map((_t) => _t.key).includes(t.key),
      // ),
      ...this.treeDataMap.filter((x) => val.checked.includes(x.key)),
    ];
    // val.checked?.map((v) => {
    //   this.treeData.map((x) => {
    //     v === x.key
    //       ? checkedNodes.push(x)
    //       : x.children?.map((y) => {
    //           v === y.key
    //             ? checkedNodes.push(y)
    //             : y.children?.map((z) => {
    //                 v === z.key && checkedNodes.push(z);
    //               });
    //         });
    //   });
    // });

    const checkedKeys = checkedNodes.map((x) => x.key),
      checkAll =
        !!checkedKeys.length &&
        checkedKeys.length >= this.treeData.length &&
        this.treeData.every((t) => checkedKeys.includes(t.key)),
      indeterminate = !!checkedKeys.length && checkedKeys.length < this.treeData.length;

    // const checkedKeys = checkedNodes.map(x => x.key),
    //     checkAll = !!checkedKeys.length && checkedKeys.length === this.treeDataMap.length,
    //     indeterminate = !!checkedKeys.length && checkedKeys.length < this.treeDataMap.length;
    this.setState({
      checkedKeys,
      checkedNodes,
      checkAll,
      indeterminate,
    });
  };

  _onExpandTree = (expandedKeys) => {
    this.setState({
      expandedKeys,
      autoExpandParent: false,
    });
  };

  _onRemove = (idx) => {
    let { checkedKeys, checkedNodes } = this.state;
    checkedNodes.splice(idx, 1);
    checkedKeys = checkedNodes.map((x) => x.key);
    this.setState({
      checkedKeys,
      checkedNodes,
      indeterminate: !!checkedKeys.length,
    });
  };

  _onCancel = () => {
    this.setState({
      visible: false,
    });
    this.props.onPress({ index: 0 });
  };

  _onOk = () => {
    const { checkedKeys, checkedNodes } = this.state;
    this.setState({
      visible: false,
    });
    this.props.onPress({
      index: 1,
      checkedKeys,
      checkedNodes,
    });
  };

  getCheckedNodes = () => {
    let arr = [];
    // 平铺数组
    const flatArr = (v) => {
      v?.map((i) => {
        arr.push(i);
        if (i.children instanceof Array) {
          flatArr(i.children);
        }
      });
    };
    flatArr(this.treeData);
    this.state.checkedKeys?.map((i) => {
      arr = arr.filter((a) => a.key !== i);
    });
    return arr;
  };

  _invertClick = () => {
    const checkedNodes = this.getCheckedNodes();
    const checkedKeys = checkedNodes.map((x) => x.key);
    this.setState({
      checkedKeys,
      checkedNodes,
    });
  };

  _changeSearchChecked = (checked) => {
    this.setState(
      {
        searchChecked: checked,
      },
      () => {
        this._onSearch(this.state.searchValue);
      },
    );
  };

  orderSort(obj1, obj2) {
    var a = obj1.title;
    var b = obj2.title;
    if (b > a) {
      return -1;
    } else if (b < a) {
      return 1;
    } else {
      return 0;
    }
  }

  render() {
    const { title = '结算单元' } = this.props;
    const {
      visible,
      checkAll,
      indeterminate,
      autoExpandParent,
      checkedKeys = [],
      checkedNodes = [],
      expandedKeys = [],
      searchValue = '',
      checkInvert,
    } = this.state;
    const loop = (data = []) =>
      data.map((item) => {
        const { lv, parentKey, key } = item;
        const index = item.title.indexOf(searchValue);
        const beforeStr = item.title.substr(0, index);
        const afterStr = item.title.substr(index + searchValue.length);
        const title =
          index > -1 ? (
            <span>
              {beforeStr}
              <span className={styles.search_act}>{searchValue}</span>
              {afterStr}
            </span>
          ) : (
            <span>{item.title}</span>
          );
        if (item.children) {
          return { ...item, key, title, lv, parentKey, children: loop(item.children) };
        }
        return { ...item, key, title, lv, parentKey };
      });
    const _renderCell = (t) => {
      return {
        ...t,
        title: (
          <div className={styles.cell}>
            <div className={styles.node_title}>{t.stationName}</div>
            <div className={styles.node_flex}>
              <div className={t.tradeRole === '1' ? styles.type_buy : styles.type_sale}>
                {t.tradeRole === '1' ? '买入' : '卖出'}
              </div>
              <Tooltip title={t.title}>
                <span className={styles.text}>{t.title}</span>
              </Tooltip>
            </div>
          </div>
        ),
        children: t.children?.map(_renderCell),
      };
    };
    return (
      <Modal
        width={800}
        className={styles.modal}
        visible={visible}
        centered={true}
        maskClosable={true}
        title={
          <div key="title" className={styles.modal_title}>
            {title}
          </div>
        }
        onCancel={this._onCancel}
        okText={'提交'}
        onOk={this._onOk}
      >
        <div className={styles.modal_body}>
          <div className={styles.treebox}>
            <div className={styles.box_header}>
              <Input
                placeholder="搜索"
                suffix={<SearchOutlined />}
                allowClear={true}
                onChange={(e) => this._onSearch(e.target.value)}
              />
              <Switch
                checkedChildren="包含"
                unCheckedChildren="排除"
                checked={this.state.searchChecked}
                onChange={this._changeSearchChecked}
                style={{ width: '70px', marginLeft: '10px' }}
              />
            </div>
            {!this.treeData.length ? (
              <div className={styles.emty}>
                <TRDefault type="emptysm" />
              </div>
            ) : (
              <>
                {this.multiple && (
                  <div className={styles.box_header}>
                    <Space>
                      <Checkbox
                        checked={checkAll}
                        indeterminate={indeterminate}
                        onChange={this._onChangeAll}
                      >
                        全选
                      </Checkbox>
                      <Button size={'small'} type="link" ghost onClick={this._invertClick}>
                        反选
                      </Button>
                    </Space>
                    <div>{`已选${checkedNodes.length}项`}</div>
                  </div>
                )}
                <div className={styles.box_content}>
                  <Tree
                    treeData={loop(this.treeData).map(_renderCell)}
                    blockNode={true}
                    checkable={true}
                    checkedKeys={checkedKeys}
                    checkStrictly
                    selectable={false}
                    expandedKeys={expandedKeys}
                    autoExpandParent={true}
                    onExpand={this._onExpandTree}
                    onCheck={this._onCheckTree}
                    height={480}
                    ref={(e) => (this.refTree = e)}
                  />
                </div>
              </>
            )}
          </div>
        </div>
      </Modal>
    );
  }
}

class TRCheckboxModal {
  __key__ = '';

  show = (props) => {
    return new Promise((resolve) => {
      if (this.__key__ !== '') return;
      this.__key__ = String(Date.now());
      TRNotification.add({
        key: this.__key__,
        content: (
          <ModalComponent
            {...props}
            onPress={(result) => {
              TRNotification.remove(this.__key__);
              this.__key__ = '';
              resolve(result);
            }}
          />
        ),
        duration: null,
      });
    });
  };

  dismiss = () => {
    if (this.__key__.length > 0) {
      TRNotification.remove(this.__key__);
      this.__key__ = '';
    }
  };
}

export default new TRCheckboxModal();
